/*
 * Copyright 2025 coze-dev Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package vo

import (
	"fmt"

	"github.com/coze-dev/coze-studio/backend/api/model/app/bot_common"
	"github.com/coze-dev/coze-studio/backend/api/model/workflow"
	"github.com/coze-dev/coze-studio/backend/pkg/i18n"
	"github.com/coze-dev/coze-studio/backend/pkg/lang/ternary"
)

// Canvas is the definition of FRONTEND schema for a workflow.
type Canvas struct {
	Nodes    []*Node `json:"nodes"`
	Edges    []*Edge `json:"edges"`
	Versions any     `json:"versions"`
}

// Node represents a node within a workflow canvas.
type Node struct {
	// ID is the unique node ID within the workflow.
	// In normal use cases, this ID is generated by frontend.
	// It does NOT need to be unique between parent workflow and sub workflows.
	// The Entry node and Exit node of a workflow always have fixed node IDs: 100001 and 900001.
	ID string `json:"id"`

	// Type is the Node Type of this node instance.
	// It corresponds to the string value of 'ID' field of NodeMeta.
	Type string `json:"type"`

	// Meta holds meta data used by frontend, such as the node's position within canvas.
	Meta any `json:"meta"`

	// Data holds the actual configurations of a node, such as inputs, outputs and exception handling.
	// It also holds exclusive configurations for different node types, such as LLM configurations.
	Data *Data `json:"data"`

	// Blocks holds the sub nodes of this node.
	// It is only used when the node type is Composite, such as NodeTypeBatch and NodeTypeLoop.
	Blocks []*Node `json:"blocks,omitempty"`

	// Edges are the connections between nodes.
	// Strictly corresponds to connections drawn on canvas.
	Edges []*Edge `json:"edges,omitempty"`

	// Version is the version of this node type's schema.
	Version string `json:"version,omitempty"`

	parent *Node // if this node is within a composite node, coze will set this. No need to set manually
}

func (n *Node) SetParent(parent *Node) {
	n.parent = parent
}

func (n *Node) Parent() *Node {
	return n.parent
}

type NodeMetaFE struct {
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
	Icon        string `json:"icon,omitempty"`
	SubTitle    string `json:"subTitle,omitempty"`
	MainColor   string `json:"mainColor,omitempty"`
}

type Edge struct {
	SourceNodeID string `json:"sourceNodeID"`
	TargetNodeID string `json:"targetNodeID"`
	SourcePortID string `json:"sourcePortID,omitempty"`
	TargetPortID string `json:"targetPortID,omitempty"`
}

// Data holds the actual configuration of a Node.
type Data struct {
	// Meta is the meta data of this node. Only used by frontend.
	Meta *NodeMetaFE `json:"nodeMeta,omitempty"`

	// Outputs configures the output fields and their types.
	// Outputs can be either []*Variable (most of the cases, just fields and types),
	// or []*Param (used by composite nodes as they need to refer to outputs of sub nodes)
	Outputs []any `json:"outputs,omitempty"`

	// Inputs configures ALL input information of a node,
	// including fixed input fields and dynamic input fields defined by user.
	Inputs *Inputs `json:"inputs,omitempty"`

	// Size configures the size of this node in frontend.
	// Only used by NodeTypeComment.
	Size any `json:"size,omitempty"`
}

type Inputs struct {
	// InputParameters are the fields defined by user for this particular node.
	InputParameters []*Param `json:"inputParameters"`
	// ChatHistorySetting configures the chat history setting for this node in chatflow mode.
	ChatHistorySetting *ChatHistorySetting `json:"chatHistorySetting,omitempty"`
	// SettingOnError configures common error handling strategy for nodes.
	// NOTE: enable in frontend node's form first.
	SettingOnError *SettingOnError `json:"settingOnError,omitempty"`

	// NodeBatchInfo configures batch mode for nodes.
	// NOTE: not to be confused with NodeTypeBatch.
	NodeBatchInfo *NodeBatch `json:"batch,omitempty"`

	// LLMParam may be one of the LLMParam or IntentDetectorLLMParam or SimpleLLMParam.
	// Shared between most nodes requiring an ChatModel to function.
	LLMParam any `json:"llmParam,omitempty"`

	*OutputEmitter      // exclusive configurations for NodeTypeEmitter and NodeTypeExit in Answer mode
	*Exit               // exclusive configurations for NodeTypeExit
	*LLM                // exclusive configurations for NodeTypeLLM
	*Loop               // exclusive configurations for NodeTypeLoop
	*Selector           // exclusive configurations for NodeTypeSelector
	*TextProcessor      // exclusive configurations for NodeTypeTextProcessor
	*SubWorkflow        // exclusive configurations for NodeTypeSubWorkflow
	*IntentDetector     // exclusive configurations for NodeTypeIntentDetector
	*DatabaseNode       // exclusive configurations for various Database nodes
	*HttpRequestNode    // exclusive configurations for NodeTypeHTTPRequester
	*Knowledge          // exclusive configurations for various Knowledge nodes
	*CodeRunner         // exclusive configurations for NodeTypeCodeRunner
	*PluginAPIParam     // exclusive configurations for NodeTypePlugin
	*VariableAggregator // exclusive configurations for NodeTypeVariableAggregator
	*VariableAssigner   // exclusive configurations for NodeTypeVariableAssigner
	*QA                 // exclusive configurations for NodeTypeQuestionAnswer
	*Batch              // exclusive configurations for NodeTypeBatch
	*Comment            // exclusive configurations for NodeTypeComment
	*InputReceiver      // exclusive configurations for NodeTypeInputReceiver
}

type OutputEmitter struct {
	Content         *BlockInput `json:"content"`
	StreamingOutput bool        `json:"streamingOutput,omitempty"`
}

type Exit struct {
	TerminatePlan *TerminatePlan `json:"terminatePlan,omitempty"`
}

type LLM struct {
	FCParam *FCParam `json:"fcParam,omitempty"`
}

type Loop struct {
	LoopType           LoopType    `json:"loopType,omitempty"`
	LoopCount          *BlockInput `json:"loopCount,omitempty"`
	VariableParameters []*Param    `json:"variableParameters,omitempty"`
}

type Selector struct {
	Branches []*struct {
		Condition struct {
			Logic      LogicType    `json:"logic"`
			Conditions []*Condition `json:"conditions"`
		} `json:"condition"`
	} `json:"branches,omitempty"`
}

type Comment struct {
	SchemaType string `json:"schemaType,omitempty"`
	Note       any    `json:"note,omitempty"`
}

type TextProcessor struct {
	Method       TextProcessingMethod `json:"method,omitempty"`
	ConcatParams []*Param             `json:"concatParams,omitempty"`
	SplitParams  []*Param             `json:"splitParams,omitempty"`
}

type VariableAssigner struct {
	VariableTypeMap map[string]any `json:"variableTypeMap,omitempty"`
}

type LLMParam = []*Param
type IntentDetectorLLMParam = map[string]any
type SimpleLLMParam struct {
	GenerationDiversity string         `json:"generationDiversity"`
	MaxTokens           int            `json:"maxTokens"`
	ModelName           string         `json:"modelName"`
	ModelType           int64          `json:"modelType"`
	ResponseFormat      ResponseFormat `json:"responseFormat"`
	SystemPrompt        string         `json:"systemPrompt"`
	Temperature         float64        `json:"temperature"`
	TopP                float64        `json:"topP"`
}

type QA struct {
	AnswerType    QAAnswerType `json:"answer_type"`
	Limit         int          `json:"limit,omitempty"`
	ExtractOutput bool         `json:"extra_output,omitempty"`
	OptionType    QAOptionType `json:"option_type,omitempty"`
	Options       []struct {
		Name string `json:"name"`
	} `json:"options,omitempty"`
	Question      string      `json:"question,omitempty"`
	DynamicOption *BlockInput `json:"dynamic_option,omitempty"`
}

type QAAnswerType string

const (
	QAAnswerTypeOption QAAnswerType = "option"
	QAAnswerTypeText   QAAnswerType = "text"
)

type QAOptionType string

const (
	QAOptionTypeStatic  QAOptionType = "static"
	QAOptionTypeDynamic QAOptionType = "dynamic"
)

type RequestParameter struct {
	Name string
}

type FCParam struct {
	WorkflowFCParam *struct {
		WorkflowList []struct {
			WorkflowID      string `json:"workflow_id"`
			WorkflowVersion string `json:"workflow_version"`
			PluginID        string `json:"plugin_id"`
			PluginVersion   string `json:"plugin_version"`
			IsDraft         bool   `json:"is_draft"`
			FCSetting       *struct {
				RequestParameters  []*workflow.APIParameter `json:"request_params"`
				ResponseParameters []*workflow.APIParameter `json:"response_params"`
			} `json:"fc_setting,omitempty"`
		} `json:"workflowList,omitempty"`
	} `json:"workflowFCParam,omitempty"`
	PluginFCParam *struct {
		PluginList []struct {
			PluginID      string `json:"plugin_id"`
			ApiId         string `json:"api_id"`
			ApiName       string `json:"api_name"`
			PluginVersion string `json:"plugin_version"`
			IsDraft       bool   `json:"is_draft"`

			PluginFrom *bot_common.PluginFrom `json:"plugin_from"`
			FCSetting  *struct {
				RequestParameters  []*workflow.APIParameter `json:"request_params"`
				ResponseParameters []*workflow.APIParameter `json:"response_params"`
			} `json:"fc_setting,omitempty"`
		} `json:"pluginList,omitempty"`
	} `json:"pluginFCParam,omitempty"`

	KnowledgeFCParam *struct {
		GlobalSetting *struct {
			SearchMode                   int64   `json:"search_mode"`
			TopK                         int64   `json:"top_k"`
			MinScore                     float64 `json:"min_score"`
			UseNL2SQL                    bool    `json:"use_nl2_sql"`
			UseRewrite                   bool    `json:"use_rewrite"`
			UseRerank                    bool    `json:"use_rerank"`
			NoRecallReplyCustomizePrompt string  `json:"no_recall_reply_customize_prompt"`
			NoRecallReplyMode            int64   `json:"no_recall_reply_mode"`
		} `json:"global_setting,omitempty"`
		KnowledgeList []*struct {
			ID string `json:"id"`
		} `json:"knowledgeList,omitempty"`
	} `json:"knowledgeFCParam,omitempty"`
}

type Batch struct {
	BatchSize      *BlockInput `json:"batchSize,omitempty"`
	ConcurrentSize *BlockInput `json:"concurrentSize,omitempty"`
}

type NodeBatch struct {
	BatchEnable    bool     `json:"batchEnable"`
	BatchSize      int64    `json:"batchSize"`
	ConcurrentSize int64    `json:"concurrentSize"`
	InputLists     []*Param `json:"inputLists,omitempty"`
}

type IntentDetectorLLMConfig struct {
	ModelName      string     `json:"modelName"`
	ModelType      int        `json:"modelType"`
	Temperature    *float64   `json:"temperature"`
	TopP           *float64   `json:"topP"`
	MaxTokens      int        `json:"maxTokens"`
	ResponseFormat int64      `json:"responseFormat"`
	SystemPrompt   BlockInput `json:"systemPrompt"`
}

type VariableAggregator struct {
	MergeGroups []*Param `json:"mergeGroups,omitempty"`
}

type PluginAPIParam struct {
	APIParams  []*Param               `json:"apiParam"`
	PluginFrom *bot_common.PluginFrom `json:"pluginFrom"`
}

type CodeRunner struct {
	Code     string `json:"code"`
	Language int64  `json:"language"`
}

type Knowledge struct {
	DatasetParam  []*Param      `json:"datasetParam,omitempty"`
	StrategyParam StrategyParam `json:"strategyParam,omitempty"`
}

type StrategyParam struct {
	ParsingStrategy struct {
		ParsingType     string `json:"parsingType,omitempty"`
		ImageExtraction bool   `json:"imageExtraction"`
		TableExtraction bool   `json:"tableExtraction"`
		ImageOcr        bool   `json:"imageOcr"`
	} `json:"parsingStrategy,omitempty"`
	ChunkStrategy struct {
		ChunkType     string  `json:"chunkType,omitempty"`
		SeparatorType string  `json:"separatorType,omitempty"`
		Separator     string  `json:"separator,omitempty"`
		MaxToken      int64   `json:"maxToken,omitempty"`
		Overlap       float64 `json:"overlap,omitempty"`
	} `json:"chunkStrategy,omitempty"`
	IndexStrategy any `json:"indexStrategy"`
}

type HttpRequestNode struct {
	APIInfo APIInfo             `json:"apiInfo,omitempty"`
	Body    Body                `json:"body,omitempty"`
	Headers []*Param            `json:"headers"`
	Params  []*Param            `json:"params"`
	Auth    *Auth               `json:"auth"`
	Setting *HttpRequestSetting `json:"setting"`
}

type APIInfo struct {
	Method string `json:"method"`
	URL    string `json:"url"`
}
type Body struct {
	BodyType string    `json:"bodyType"`
	BodyData *BodyData `json:"bodyData"`
}
type BodyData struct {
	Json     string `json:"json,omitempty"`
	FormData *struct {
		Data []*Param `json:"data"`
	} `json:"formData,omitempty"`
	FormURLEncoded []*Param `json:"formURLEncoded,omitempty"`
	RawText        string   `json:"rawText,omitempty"`
	Binary         struct {
		FileURL *BlockInput `json:"fileURL"`
	} `json:"binary"`
}

type Auth struct {
	AuthType string `json:"authType"`
	AuthData struct {
		CustomData struct {
			AddTo string   `json:"addTo"`
			Data  []*Param `json:"data,omitempty"`
		} `json:"customData"`
		BearerTokenData []*Param `json:"bearerTokenData,omitempty"`
	} `json:"authData"`

	AuthOpen bool `json:"authOpen"`
}

type HttpRequestSetting struct {
	Timeout    int64 `json:"timeout"`
	RetryTimes int64 `json:"retryTimes"`
}

type DatabaseNode struct {
	DatabaseInfoList []*DatabaseInfo `json:"databaseInfoList,omitempty"`
	SQL              string          `json:"sql,omitempty"`
	SelectParam      *SelectParam    `json:"selectParam,omitempty"`

	InsertParam *InsertParam `json:"insertParam,omitempty"`

	DeleteParam *DeleteParam `json:"deleteParam,omitempty"`

	UpdateParam *UpdateParam `json:"updateParam,omitempty"`
}

type DatabaseLogicType string

const (
	DatabaseLogicAnd DatabaseLogicType = "AND"
	DatabaseLogicOr  DatabaseLogicType = "OR"
)

type DBCondition struct {
	ConditionList [][]*Param        `json:"conditionList,omitempty"`
	Logic         DatabaseLogicType `json:"logic"`
}

type UpdateParam struct {
	Condition DBCondition `json:"condition"`
	FieldInfo [][]*Param  `json:"fieldInfo"`
}

type DeleteParam struct {
	Condition DBCondition `json:"condition"`
}

type InsertParam struct {
	FieldInfo [][]*Param `json:"fieldInfo"`
}

type SelectParam struct {
	Condition   *DBCondition `json:"condition,omitempty"` // may be nil
	OrderByList []struct {
		FieldID int64 `json:"fieldID"`
		IsAsc   bool  `json:"isAsc"`
	} `json:"orderByList,omitempty"`
	Limit     int64 `json:"limit"`
	FieldList []struct {
		FieldID    int64 `json:"fieldID"`
		IsDistinct bool  `json:"isDistinct"`
	} `json:"fieldList,omitempty"`
}

type DatabaseInfo struct {
	DatabaseInfoID string `json:"databaseInfoID"`
}

type IntentDetector struct {
	Intents []*Intent `json:"intents,omitempty"`
	Mode    string    `json:"mode,omitempty"`
}
type ChatHistorySetting struct {
	EnableChatHistory bool  `json:"enableChatHistory,omitempty"`
	ChatHistoryRound  int64 `json:"chatHistoryRound,omitempty"`
}

type Intent struct {
	Name string `json:"name"`
}

// Param is a node's field with type and source info.
type Param struct {
	// Name is the field's name.
	Name string `json:"name,omitempty"`

	// Input is the configurations for normal, singular field.
	Input *BlockInput `json:"input,omitempty"`

	// Left is the configurations for the left half of an expression,
	// such as an assignment in NodeTypeVariableAssigner.
	Left *BlockInput `json:"left,omitempty"`

	// Right is the configuration for the right half of an expression.
	Right *BlockInput `json:"right,omitempty"`

	// Variables are configurations for a group of fields.
	// Only used in NodeTypeVariableAggregator.
	Variables []*BlockInput `json:"variables,omitempty"`
}

// Variable is the configuration of a node's field, either input or output.
type Variable struct {
	// Name is the field's name as defined on canvas.
	Name string `json:"name"`

	// Type is the field's data type, such as string, integer, number, object, array, etc.
	Type VariableType `json:"type"`

	// Required is set to true if you checked the 'required box' on this field
	Required bool `json:"required,omitempty"`

	// AssistType is the 'secondary' type of string fields, such as different types of file and image, or time.
	AssistType AssistType `json:"assistType,omitempty"`

	// Schema contains detailed info for sub-fields of an object field, or element type of an array.
	Schema any `json:"schema,omitempty"` // either []*Variable (for object) or *Variable (for list)

	// Description describes the field's intended use. Used on Entry node. Useful for workflow tools.
	Description string `json:"description,omitempty"`

	// ReadOnly indicates a field is not to be set by Node's business logic.
	// e.g. the ErrorBody field when exception strategy is configured.
	ReadOnly bool `json:"readOnly,omitempty"`

	// DefaultValue configures the 'default value' if this field is missing in input.
	// Effective only in Entry node.
	DefaultValue any `json:"defaultValue,omitempty"`
}

type BlockInput struct {
	Type       VariableType     `json:"type,omitempty" yaml:"Type,omitempty"`
	AssistType AssistType       `json:"assistType,omitempty" yaml:"AssistType,omitempty"`
	Schema     any              `json:"schema,omitempty" yaml:"Schema,omitempty"` // either *BlockInput(or *Variable) for list or []*Variable (for object)
	Value      *BlockInputValue `json:"value,omitempty" yaml:"Value,omitempty"`
}

type BlockInputValue struct {
	Type    BlockInputValueType `json:"type"`
	Content any                 `json:"content,omitempty"` // either string for text such as template, or BlockInputReference
	RawMeta any                 `json:"rawMeta,omitempty"`
}

type BlockInputReference struct {
	BlockID string        `json:"blockID"`
	Name    string        `json:"name,omitempty"`
	Path    []string      `json:"path,omitempty"`
	Source  RefSourceType `json:"source"`
}

type Condition struct {
	Operator OperatorType `json:"operator"`
	Left     *Param       `json:"left"`
	Right    *Param       `json:"right,omitempty"`
}

type SubWorkflow struct {
	WorkflowID      string `json:"workflowId,omitempty"`
	WorkflowVersion string `json:"workflowVersion,omitempty"`
	TerminationType int    `json:"type,omitempty"`
	SpaceID         string `json:"spaceId,omitempty"`
}

type VariableType string

const (
	VariableTypeString  VariableType = "string"
	VariableTypeInteger VariableType = "integer"
	VariableTypeFloat   VariableType = "float"
	VariableTypeBoolean VariableType = "boolean"
	VariableTypeObject  VariableType = "object"
	VariableTypeList    VariableType = "list"
)

type AssistType = int64

const (
	AssistTypeNotSet  AssistType = 0
	AssistTypeDefault AssistType = 1
	AssistTypeImage   AssistType = 2
	AssistTypeDoc     AssistType = 3
	AssistTypeCode    AssistType = 4
	AssistTypePPT     AssistType = 5
	AssistTypeTXT     AssistType = 6
	AssistTypeExcel   AssistType = 7
	AssistTypeAudio   AssistType = 8
	AssistTypeZip     AssistType = 9
	AssistTypeVideo   AssistType = 10
	AssistTypeSvg     AssistType = 11
	AssistTypeVoice   AssistType = 12

	AssistTypeTime AssistType = 10000
)

type BlockInputValueType string

const (
	BlockInputValueTypeLiteral   BlockInputValueType = "literal"
	BlockInputValueTypeRef       BlockInputValueType = "ref"
	BlockInputValueTypeObjectRef BlockInputValueType = "object_ref"
)

type RefSourceType string

const (
	RefSourceTypeBlockOutput  RefSourceType = "block-output" // Represents an implicitly declared variable that references the output of a block
	RefSourceTypeGlobalApp    RefSourceType = "global_variable_app"
	RefSourceTypeGlobalSystem RefSourceType = "global_variable_system"
	RefSourceTypeGlobalUser   RefSourceType = "global_variable_user"
)

type TerminatePlan string

const (
	ReturnVariables  TerminatePlan = "returnVariables"
	UseAnswerContent TerminatePlan = "useAnswerContent"
)

type ErrorProcessType int

const (
	ErrorProcessTypeThrow             ErrorProcessType = 1 // throws the error as usual
	ErrorProcessTypeReturnDefaultData ErrorProcessType = 2 // return DataOnErr configured in SettingOnError
	ErrorProcessTypeExceptionBranch   ErrorProcessType = 3 // executes the exception branch on error
)

// SettingOnError contains common error handling strategy.
type SettingOnError struct {
	// DataOnErr defines the JSON result to be returned on error.
	DataOnErr string `json:"dataOnErr,omitempty"`
	// Switch defines whether ANY error handling strategy is active.
	// If set to false, it's equivalent to set ProcessType = ErrorProcessTypeThrow
	Switch bool `json:"switch,omitempty"`
	// ProcessType determines the error handling strategy for this node.
	ProcessType *ErrorProcessType `json:"processType,omitempty"`
	// RetryTimes determines how many times to retry. 0 means no retry.
	// If positive, any retries will be executed immediately after error.
	RetryTimes int64 `json:"retryTimes,omitempty"`
	// TimeoutMs sets the timeout duration in millisecond.
	// If any retry happens, ALL retry attempts accumulates to the same timeout threshold.
	TimeoutMs int64 `json:"timeoutMs,omitempty"`
	// Ext sets any extra settings specific to NodeType
	Ext *struct {
		// BackupLLMParam is only for LLM Node, marshaled from SimpleLLMParam.
		// If retry happens, the backup LLM will be used instead of the main LLM.
		BackupLLMParam string `json:"backupLLMParam,omitempty"`
	} `json:"ext,omitempty"`
}

type LogicType int

const (
	_ LogicType = iota
	OR
	AND
)

type OperatorType int

const (
	_ OperatorType = iota
	Equal
	NotEqual
	LengthGreaterThan
	LengthGreaterThanEqual
	LengthLessThan
	LengthLessThanEqual
	Contain
	NotContain
	Empty
	NotEmpty
	True
	False
	GreaterThan
	GreaterThanEqual
	LessThan
	LessThanEqual
)

type TextProcessingMethod string

const (
	Concat TextProcessingMethod = "concat"
	Split  TextProcessingMethod = "split"
)

type LoopType string

const (
	LoopTypeArray    LoopType = "array"
	LoopTypeCount    LoopType = "count"
	LoopTypeInfinite LoopType = "infinite"
)

type InputReceiver struct {
	OutputSchema string `json:"outputSchema,omitempty"`
}

func GenerateNodeIDForBatchMode(key string) string {
	return key + "_inner"
}

func IsGeneratedNodeForBatchMode(key string, parentKey string) bool {
	return key == GenerateNodeIDForBatchMode(parentKey)
}

const defaultZhCNInitCanvasJsonSchema = `{
 "nodes": [
  {
   "id": "100001",
   "type": "1",
   "meta": {
    "position": {
     "x": 0,
     "y": 0
    }
   },
   "data": {
    "nodeMeta": {
     "description": "工作流的起始节点，用于设定启动工作流需要的信息",
     "icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
     "subTitle": "",
     "title": "开始"
    },
    "outputs": [
     {
      "type": "string",
      "name": "input",
      "required": false
     }
    ],
    "trigger_parameters": [
     {
      "type": "string",
      "name": "input",
      "required": false
     }
    ]
   }
  },
  {
   "id": "900001",
   "type": "2",
   "meta": {
    "position": {
     "x": 1000,
     "y": 0
    }
   },
   "data": {
    "nodeMeta": {
     "description": "工作流的最终节点，用于返回工作流运行后的结果信息",
     "icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
     "subTitle": "",
     "title": "结束"
    },
    "inputs": {
     "terminatePlan": "returnVariables",
     "inputParameters": [
      {
       "name": "output",
       "input": {
        "type": "string",
        "value": {
         "type": "ref",
         "content": {
          "source": "block-output",
          "blockID": "",
          "name": ""
         }
        }
       }
      }
     ]
    }
   }
  }
 ],
 "edges": [],
 "versions": {
  "loop": "v2"
 }
}`

const defaultEnUSInitCanvasJsonSchema = `{
 "nodes": [
  {
   "id": "100001",
   "type": "1",
   "meta": {
    "position": {
     "x": 0,
     "y": 0
    }
   },
   "data": {
    "nodeMeta": {
     "description": "The starting node of the workflow, used to set the information needed to initiate the workflow.",
     "icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
     "subTitle": "",
     "title": "Start"
    },
    "outputs": [
     {
      "type": "string",
      "name": "input",
      "required": false
     }
    ],
    "trigger_parameters": [
     {
      "type": "string",
      "name": "input",
      "required": false
     }
    ]
   }
  },
  {
   "id": "900001",
   "type": "2",
   "meta": {
    "position": {
     "x": 1000,
     "y": 0
    }
   },
   "data": {
    "nodeMeta": {
     "description": "The final node of the workflow, used to return the result information after the workflow runs.",
     "icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
     "subTitle": "",
     "title": "End"
    },
    "inputs": {
     "terminatePlan": "returnVariables",
     "inputParameters": [
      {
       "name": "output",
       "input": {
        "type": "string",
        "value": {
         "type": "ref",
         "content": {
          "source": "block-output",
          "blockID": "",
          "name": ""
         }
        }
       }
      }
     ]
    }
   }
  }
 ],
 "edges": [],
 "versions": {
  "loop": "v2"
 }
}`

const defaultZhCNInitCanvasJsonSchemaChat = `{
	"nodes": [{
		"id": "100001",
		"type": "1",
		"meta": {
			"position": {
				"x": 0,
				"y": 0
			}
		},
		"data": {
			"outputs": [{
				"type": "string",
				"name": "USER_INPUT",
				"required": true
			}, {
				"type": "string",
				"name": "CONVERSATION_NAME",
				"required": false,
				"description": "本次请求绑定的会话，会自动写入消息、会从该会话读对话历史。",
				"defaultValue": "%s"
			}],
			"nodeMeta": {
				"title": "开始",
				"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
				"description": "工作流的起始节点，用于设定启动工作流需要的信息",
				"subTitle": ""
			}
		}
	}, {
		"id": "900001",
		"type": "2",
		"meta": {
			"position": {
				"x": 1000,
				"y": 0
			}
		},
		"data": {
			"nodeMeta": {
				"title": "结束",
				"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
				"description": "工作流的最终节点，用于返回工作流运行后的结果信息",
				"subTitle": ""
			},
			"inputs": {
				"terminatePlan": "useAnswerContent",
				"streamingOutput": true,
				"inputParameters": [{
					"name": "output",
					"input": {
						"type": "string",
						"value": {
							"type": "ref"
						}
					}
				}]
			}
		}
	}]
}`
const defaultEnUSInitCanvasJsonSchemaChat = `{
	"nodes": [{
		"id": "100001",
		"type": "1",
		"meta": {
			"position": {
				"x": 0,
				"y": 0
			}
		},
		"data": {
			"outputs": [{
				"type": "string",
				"name": "USER_INPUT",
				"required": true
			}, {
				"type": "string",
				"name": "CONVERSATION_NAME",
				"required": false,
				"description": "The conversation bound to this request will automatically write messages and read conversation history from that conversation.",
				"defaultValue": "%s"
			}],
			"nodeMeta": {
				"title": "Start",
				"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-Start.png",
				"description": "The starting node of the workflow, used to set the information needed to initiate the workflow.",
				"subTitle": ""
			}
		}
	}, {
		"id": "900001",
		"type": "2",
		"meta": {
			"position": {
				"x": 1000,
				"y": 0
			}
		},
		"data": {
			"nodeMeta": {
				"title": "End",
				"icon": "https://lf3-static.bytednsdoc.com/obj/eden-cn/dvsmryvd_avi_dvsm/ljhwZthlaukjlkulzlp/icon/icon-End.png",
				"description": "The final node of the workflow, used to return the result information after the workflow runs.",
				"subTitle": ""
			},
			"inputs": {
				"terminatePlan": "useAnswerContent",
				"streamingOutput": true,
				"inputParameters": [{
					"name": "output",
					"input": {
						"type": "string",
						"value": {
							"type": "ref"
						}
					}
				}]
			}
		}
	}]
}`

func GetDefaultInitCanvasJsonSchema(locale i18n.Locale) string {
	return ternary.IFElse(locale == i18n.LocaleEN, defaultEnUSInitCanvasJsonSchema, defaultZhCNInitCanvasJsonSchema)
}

func GetDefaultInitCanvasJsonSchemaChat(locale i18n.Locale, name string) string {
	return ternary.IFElse(locale == i18n.LocaleEN, fmt.Sprintf(defaultEnUSInitCanvasJsonSchemaChat, name), fmt.Sprintf(defaultZhCNInitCanvasJsonSchemaChat, name))
}
